require "Common/define"
require "Logic/Config"
require "Common/functions"

---@class TowerManager
TowerManager = {};
local this = TowerManager;

local towerData = nil;
local towerTeamData = nil;
local itemData = nil;
local heroData = nil;
local towerTypeData = nil;
local advancedTower = nil;
local timeData = nil;
local allTowerData = {};

local towerRankMap = {};
local towerMyRankMap = {};
local towerRankVersionMap = {};

function TowerManager.init()
    towerData = G.dataTable["t_tower"];
    itemData = G.dataTable["t_item"];
    heroData = G.dataTable["t_hero"];
    towerTeamData = dataTable.getDataTable("t_towermonsterteam");
    towerTypeData = G.dataTable["t_towertype"]
    timeData = G.dataTable["t_time"]
end
function TowerManager.ShowUIBattleTeam()
    this.showUIBattleTeamImmediate = true
end
--处理接收的爬塔数据
function TowerManager.saveTowerInfo(msg)
    local towerInfo = msg.towerInfo;
    allTowerData = {};
    for i = 1, #towerInfo do
        local tower = {};
        local id = tostring(towerInfo[i].layerId + 1);
        tower["layerId"] = id;
        tower["towerType"] = towerInfo[i].towerType;
        tower["todayLayer"] = towerInfo[i].todayLayer;
        --阵型
        tower["formation"] ={};
        for k = 1, #towerInfo[i].formation do
            table.insert(tower["formation"],tostring(towerInfo[i].formation[k]));
        end
        local formationType = G.dataTable["t_towertype"][tostring(msg.towerInfo[i].towerType)]["f_FormationType"];
        logicMgr.FormationManager.SetFormation(formationType,tower["formation"]);
        table.insert(allTowerData,tower);
    end

    --msg.towerInfo = nil;
    logicMgr.TATrackCollect.Track_ClimbTower()
end

function TowerManager.addLayer(type, layerId, todayLayer)
    for i = 1, #allTowerData do
        if tonumber(allTowerData[i].towerType) == tonumber(type) then
            this.setLastLayerId(type, allTowerData[i].layerId);
            allTowerData[i].layerId =  layerId;
            allTowerData[i].todayLayer =  todayLayer or 0;
        end
    end
end

function TowerManager.setLastLayerId(type, id)
    if this.lastLayerId == nil then
        this.lastLayerId = {};
    end
    this.lastLayerId[type] = id;
end

function TowerManager.getLastLayerId(type)
    if this.lastLayerId == nil then
        return nil;
    end
    return this.lastLayerId[type];
end

--- @param msg ResTowerGetRanksMessage
function TowerManager.setRanks(msg)
    local localRankVer = towerRankVersionMap[msg.towerType] or -1;
    if msg.rankVersion == localRankVer then
        --return
    end

    towerRankVersionMap[msg.towerType] = msg.rankVersion
    towerRankMap[msg.towerType] = msg.ranks or {}
    --table.sort(towerRankMap[msg.towerType], function (a, b)
    --    if a.score > b.score then return true; end
    --    if a.score < b.score then return false; end
    --    if a.time < b.time then return true; end
    --    if a.time > b.time then return false; end
    --    return tonumber(tostring(a.playerId)) < tonumber(tostring(b.playerId));
    --end)

    local roleInfo = logicMgr.HeroManager.GetRoleInfo()
    local myRankData = TowerRankInfo.New()

    myRankData.playerId = roleInfo.playerId
    myRankData.name = roleInfo.name
    myRankData.headIcon = roleInfo.pic
    myRankData.headFrame = roleInfo.picFrame
    myRankData.level = roleInfo.level
    myRankData.score = tonumber(this.returnTowerInfo(msg.towerType)["layerId"]) - 1;
    myRankData.time = 0

    towerMyRankMap[msg.towerType] = {
        rank = msg.myRank + 1,
        data = myRankData
    }

    FireEvent(Config.EventType.Fresh_TowerRanks)
end

--返回爬塔数据
function TowerManager.returnTowerInfo(type)
    for i = 1, #allTowerData do
        if tonumber(allTowerData[i].towerType) == tonumber(type) then
            return allTowerData[i];
        end
    end
    return nil;
end

--根据爬塔类型和层数拿奖励
function TowerManager.returnReward(towerType, towerLevel)
    if towerLevel == 0 then
        towerLevel = 1;
    end
    local rewardList = {};
    local rewardInfo = towerData[tostring((towerType-1)*10000 + towerLevel)];
    if rewardInfo then
        local Reward = decodeJsonStrToTabel(towerData[tostring((towerType-1)*10000 + towerLevel)].f_Reward);

        for i = 1, #Reward do
            local rewardInfo = logicMgr.CostManager.getItemOrEquipDataByIdAndNum(Reward[i][1], Reward[i][2]);
            table.insert(rewardList,rewardInfo);
        end
    end

    return rewardList;
end

-- 根据爬塔类型和层数获取展示奖励
function TowerManager.getSpecialReward(towerType, towerLevel)
    if towerLevel == 0 then
        towerLevel = 1;
    end

    local rewardInfo = towerData[tostring((towerType-1)*10000 + towerLevel)];
    if rewardInfo then
        local reward = rewardInfo.f_SpecialRewardShow;
        if reward ~= nil and reward ~= "" then
            return reward;
        end
    end

    return nil;
end

function TowerManager.sendGetRanks(towerType)
    towerHandler.sendGetRanks(towerType, (towerRankVersionMap[towerType] or -1))
end

function TowerManager.getTowerMonsterTeam(type)
    local tower = this.returnTowerInfo(type);
    if tower~=nil then
        local towerCg = towerData[tostring(((type-1)*10000)+tower.layerId)];
        local teamCg = towerTeamData[tostring(towerCg.f_TowerMonsterTeamId)];

        local info = {};
        info["stactics"] = teamCg.f_TacticsId_Id;
        info["team"] = {};
        for i = 1,6 do
            local monster =decodeJsonStrToTabel(teamCg["f_MonsterPara"..i]);
            table.insert(info["team"],monster);
        end
        info["power"] = teamCg["f_Combat_Effectiveness"] or 0;
        return info;
    end
    return nil;
end

function TowerManager.getRanks(towerType)
    return clone(towerRankMap[towerType] or {});
end

function TowerManager.getMyRank(towerType)
    return clone(towerMyRankMap[towerType] or {
        rank = -1,
        data = {}
    });
end

function TowerManager.getBattleMapId()
    local mapId = "AutoFightMap26";
    local data = this.getLastLayerId(1);
    if data ~= nil then
        mapId = towerData[tostring(data)].f_BattleMap;
    end
    return mapId;
end
function TowerManager.getTowerJumpLayer(towerType, towerLevel)
    local rewardInfo = towerData[tostring((towerType-1)*10000 + towerLevel)];
    if rewardInfo then
        return rewardInfo.f_SkipStageTarget;
    end
    return 0;
end

function TowerManager.enterTower()
    local flag = GetPlayerPrefsAfter5AMFlag("_enter_tower:")
    if flag then
        SetPlayerPrefsAfter5AMFlag("_enter_tower:")
        RedDotsClimbTowerHandler.update();
    end
end

function TowerManager.hasRedPoint()
    local flag = GetPlayerPrefsAfter5AMFlag("_enter_tower:")
    return flag
end

function TowerManager.setPlayStart(start)
    this.playStart = start;
end

function TowerManager.getPlayStart()
    return this.playStart;
end

--设置当前爬塔类型
function TowerManager.setClimbType(type)
    this.climbType = type;
end

--获取当前爬塔类型
function TowerManager.getClimbType()
    return this.climbType or 1;
end

function TowerManager.getAdvancedTowerTypeData()
    if advancedTower == nil then
        advancedTower = {}
        for _,v in pairs(towerTypeData) do
            if v.f_Group == EnumConst.TowerType.Advanced then
                table.insert(advancedTower,v);
            end
        end
        table.sort(advancedTower,function(a,b) return a.f_TowerType<b.f_TowerType end)
    end

    return advancedTower or {}
end

--获取当前时间开启的职业爬塔类型
function TowerManager.getAdvancedTowerOpenType()
    local nowOpenType = {}
    if not advancedTower then
        this.getAdvancedTowerTypeData();
    end
    for k,v in pairs(advancedTower) do
        local curTime = HelperFunc.GetServerTime()
        local lastTime = tonumber(timeData[tostring(v.f_LastTime)].f_string_value)
        local nextOpenTime = tonumber(logicMgr.CronMgr.GetNextDateTime(timeData[tostring(v.f_RefreshTime)].f_string_value,curTime - lastTime))
        if nextOpenTime < curTime then
            table.insert(nowOpenType, v.f_TowerType)
        end
    end
    return nowOpenType;
end

--获取当前职业爬塔类型所能选择的英雄类型
function TowerManager.getAdvancedTowerHeroType(type)
    local curTowerType = type or this.getClimbType();
    local canSelectHeroType = decodeJsonStrToTabel(towerTypeData[tostring(curTowerType)].f_PlayerHeroTypeLimit)
    return canSelectHeroType or {}
end

--获取职业爬塔敌方英雄类型
function TowerManager.getAdvancedTowerEnemyType(type)
    local canSelectHeroType = decodeJsonStrToTabel(towerTypeData[tostring(type)].f_TowerHeroTypeShow)
    return canSelectHeroType or {}
end

--获取职业爬塔每日推塔上限
function TowerManager.getAdvancedTowerToDayLimit(type)
    return towerTypeData[tostring(type)].f_limit
end

--获取爬塔纪录
function TowerManager.getClimbTowerRecordData()
    return this.recordData;
end

--设置爬塔纪录
function TowerManager.setClimbTowerRecordData(data)
    this.recordData = data;
end

--设置爬塔是否可以跳关
function TowerManager.setIsCanSkip(flag)
    this.isCanSkip = flag;
end

--获取爬塔是否可以跳关
function TowerManager.getIsCanSkip()
    return this.isCanSkip;
end

function TowerManager.towerAutoBattle()
    local curTowerType = this.getClimbType();
    local curTowerInfo = this.returnTowerInfo(curTowerType);
    local curTowerlevel = tonumber(curTowerInfo["layerId"]);

    local _towerDic = {};
    _towerDic.tower_stage_id = tostring((curTowerType - 1)*10000 + curTowerlevel);
    TAManager.TrackByDictionary("tower_click_challenge", _towerDic);

    local cfg = dataTable.getDataTableByStringId("t_towertype", tostring(curTowerType));
    local formationType =  cfg["f_FormationType"];
    local defaultFormation = logicMgr.FormationManager.GetFormation(formationType);
    towerHandler.sendTowerBoss(curTowerType, curTowerlevel, defaultFormation);
end

return TowerManager